package com.hibernate.db;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.junit.Test;

import com.hibernate.domain.Classes;
import com.hibernate.domain.Student;
import com.hibernate.utils.HibernateUtils;

public class One2ManySingleTest extends HibernateUtils {
	
	/**
	 * 添加班级，级联添加学生
	 */
	@Test
	public void testSaveClasses_Cascade_SaveStudents() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = new Classes() ;
		classes.setCname("3班") ;
		classes.setDescription("培训3班") ;
		Set<Student> students = new HashSet<Student>() ;
		students.add(new Student("张三03","培训班学生")) ;
		students.add(new Student("李四03","培训班学生")) ;
		students.add(new Student("王五03","培训班学生")) ;
		classes.setStudents(students) ;
		session.save(classes) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 更新班级，级联更新学生
	 */
	@Test
	public void testUpdateClasses_Cascade_UpdateStudents() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 1L) ;
		Set<Student> students = classes.getStudents() ;
		for (Student student : students) {
			student.setDescription("培训班学生-更新") ;
		}
		session.flush() ;
		transaction.commit() ;
		session.close() ;
 	}
	
	/**
	 * 删除班级，解除班级与学生的关系
	 * 	<set name="students" cascade="save-update" inverse="false">
	 */
	@Test
	public void testDeleteClasses_ReleaseR() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 3L) ;
		session.delete(classes) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 删除班级，不维护与学生的关系，此时删除班级时将报错，不让删除
	 * 	<set name="students" cascade="save-update" inverse="true">
	 */
	@Test
	public void testDeleteClasses_Cascade_NotReleaseR() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 3L) ;
		session.delete(classes) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 删除班级，级联删除班级下所有的学生
	 * 	<set name="students" cascade="delete" inverse="false">
	 */
	@Test
	public void testDeleteClasses_Cascade_DeleteStudents_03() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 3L) ;
		session.delete(classes) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 解除一个学生与班级的关系
	 */
	@Test
	public void testReleaseStudent_Cascade_Classes() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 1L) ;
		Student student = (Student)session.get(Student.class, 2L) ;
		classes.getStudents().remove(student) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 将一个学生添加到指定班级
	 */
	@Test
	public void testAddStudent2Classes() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 1L) ;
		Student student = (Student)session.get(Student.class, 2L) ;
		classes.getStudents().add(student) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 解除班级与所有学生的关系
	 */
	@Test
	public void testReleaseClasses2Students() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes = (Classes)session.get(Classes.class, 2L) ;
		classes.setStudents(null) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 将一批学生添加到指定班级
	 */
	@Test
	public void testAddStudents2Classes() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Set<Student> students = new HashSet<Student>() ;
		students.add((Student)session.get(Student.class, 3L)) ;
		students.add((Student)session.get(Student.class, 4L)) ;
		students.add((Student)session.get(Student.class, 5L)) ;
		Classes classes = (Classes) session.get(Classes.class, 2L) ;
		classes.setStudents(students) ;
		transaction.commit() ;
		session.close() ;
	}
	
	/**
	 * 将某个学生从2班转到1班
	 */
	@Test
	public void testTransformClasses() {
		Session session = sessionFactory.openSession() ;
		Transaction transaction = session.beginTransaction() ;
		Classes classes2 = (Classes)session.get(Classes.class, 2L) ;
		Student student3 = (Student)session.get(Student.class, 3L) ;
		//不需要从2班中移除，直接将其添加到1班即可，实质是将cid为1直接覆盖cid为2来达到转班的目的
//		classes2.getStudents().remove(student3) ;
		Classes classes1 = (Classes) session.get(Classes.class, 1L) ;
		classes1.getStudents().add(student3) ;
		transaction.commit() ;
		session.close() ;
	}
	
}
